#ifndef CSYNCBASETHREAD_H
#define CSYNCBASETHREAD_H
/********************************************************************************
** @ Date:2025/04/07
** @ Author: HanJiaXing
** @ Description:SyncBase数据库读写线程
** @ Version:1.0.0
** @ ClassName:CEmergencyStop
** @ Fun:
********************************************************************************/
#include <QReadWriteLock>
#include <QVariant>
#include <QVector>
#include <QThread>
#include <QMutex>
#include "./include/SyncBaseApi60.h"
#include "ctag.h"
#include "cmoduleparent.h"
#include "log.h"
#include "header.h"

struct STagHistory
{
    int nUploadTimes;           //上传次数
    int nUploadLimit;           //上传重试上限
    QVector<QString> vecAddr;   //地址集合
    QVector<CTag*> vecTag;      //上传测点集合
    STagHistory()
    {
        nUploadTimes = 0;
        nUploadLimit = 2;
    }
};

struct tagVector
{
    TAGID *m_pTagId;
    TAG_DATA *m_pTagData;
    char *m_pTagQuality;
    QMap<QString, CTag *> m_mapTag;     //实时测点数据
    QMap<QString, TAGID> m_mapTagId;    //测点名称索引对照
    QMap<QString, CTag*> m_mapTagHis;   //测点历史数据
    QVector<STagHistory> m_vecTagHis;    //历史测点集合
    tagVector()
    {
        m_pTagId = NULL;
        m_pTagData = NULL;
        m_pTagQuality = NULL;
		m_mapTag.clear();
		m_mapTagId.clear();
        m_vecTagHis.clear();
    }
    ~tagVector()
    {
        SAFE_DELETE_A(m_pTagId);
        SAFE_DELETE_A(m_pTagData);
        SAFE_DELETE_A(m_pTagQuality);
        qDeleteAll(m_mapTag);
		m_mapTag.clear();
        qDeleteAll(m_mapTagHis);
        m_mapTagHis.clear();
        m_mapTagId.clear();
        m_vecTagHis.clear();
    }
};

class CSyncBaseThread : public QThread
{
    Q_OBJECT
public:
    CSyncBaseThread();
    ~CSyncBaseThread();
    void ThreadStart();//开启线程
    void ThreadStop();//停止线程
    void config(const QString& sIp,const int& nPort,const QString& sUserName,const QString& sPassWd,const QString& sDbName);//配置连接参数
	QString getConfig();//返回配置参数
    bool startSyncBase();//开启SyncBase连接
    bool stopSyncBase();//关闭SyncBase连接
    int addTag(const QString &addr, const int &nType, const unsigned int &cyc);//向读写线程中添加测点
	int delTag(const QString &addr);//向读写线程中删除测点
	void clear();//清除测点
	CTag* value(const QString &addr);//读测点
	VecPTag values(const VecStr &vecAddr);//读多个测点
	int setValue(const QString &addr, const CTag* pTag);
    int setValue(const QString &addr, CTag& pTag);
	int setValues(const VecStr &vecAddr, VecPTag vecTags);
    int setValueHistory(QString addr, CTag* pTag);
    int setValueHistory(QString addr, CTag& pTag);
    int setValuesHistory(const VecStr &vecAddr, VecPTag vecTags);

    void setLogRet(LogCallback callback);//设置日志回调函数

private:
    /********************************************************************
    功能描述：连接SyncBase数据库
    输入参数：无
    返回:true 成功 false 失败
    ********************************************************************/
    bool connectSyncBase();

	/********************************************************************
	功能描述：断开连接SyncBase数据库
	输入参数：无
	返回:true 成功 false 失败
	********************************************************************/
	bool disconnectSyncBase();

    /********************************************************************
    功能描述：创建数据库实例，必须在其它函数使用前调用
    输入参数：无
    输出参数：无
    ********************************************************************/
    void createDb();

    /********************************************************************
    功能描述：连接服务器，必须在调用其它取数据函数前调用
    输入参数：hDB - 数据库句柄
                 pszServerNameOrAddr - 路由服务器IP或计算机名
                 nPort - 服务端口号,默认8005
    输出参数：无
    返 回 值：1 - 成功
             0 - 失败
    ********************************************************************/
    int openDb();

    /********************************************************************
    功能描述：断开与服务连接
    输入参数：hDB - 数据库句柄
    输出参数：无
    返 回 值：1 - 成功
             0 - 失败
    ********************************************************************/
    int closeDb();

    /********************************************************************
    功能描述：用户登录
    输入参数：hDB - 数据库句柄
              szUser - 用户名
              szPassword - 密码
    输出参数：无
    返 回 值：1 - 成功
              0 - 失败
    ********************************************************************/
    int loginDb();

    /********************************************************************
    功能描述：用户注销
    输入参数：hDB - 数据库句柄
    输出参数：无
    返 回 值：1 - 成功
            0 - 失败
    ********************************************************************/
    int logoutDb();

    /********************************************************************
    功能描述：用户注销
    输入参数：hDB - 数据库句柄
    输出参数：无
    返 回 值：true 连接正常 fasle 连接失败
    ********************************************************************/
    bool isSyncBaseConnect();

    //获取数据库Id
    bool getBaseId();

    //初始化测点
    void initTag();

    //读测点
    void readTag();

    //读取数据解析
    void analysisReadData();

	//写测点
	void writeTag();

    //写历史测点
    void writeTagHistory();

	//测点赋值
	bool assignmentTag(D_VAL &val, CTag* pTag);

	//值类型转换成syncbase值类型
	uint8 valueTypeChange(const int &nType);

    // 将时间戳（毫秒级）转换为 MS_TIME 结构体
    MS_TIME timestampToMS_TIME(uint64_t timestamp);

    LogCallback m_lpLogCallback;

protected:
    void run() override;

private:
    std::atomic<bool>      m_bhread;         //线程状态
	QMutex    m_mutex;			//资源锁
	bool      m_bIsConnect;		//syncbase连接状态
    HSYNCBASE m_hDb;//数据库实例
    QString   m_sIp;//syncbase数据库IP地址
    int       m_nPort;//syncbase端口号
    QString   m_sUserName;//用户名
    QString   m_sPassWd;//密码
    int       m_nDbId;			//数据库Id
    QString   m_sDbName;	//数据库名（用来获取数据库Id）
    QLog      m_log;
    bool      m_bShouldStop;
    bool      m_bFrist;                           //是否是首次开启线程，防止重启启动设备的时候频繁创建线程
    bool      m_bIsInit;//是否初始化（加载数据库所有测点）
    tagVector m_vecTag;//管理的测点集合
};

#endif // CSYNCBASETHREAD_H
